package current

import (
	"encoding/json"
	"flag"
	"fmt"
	"github.com/simonvetter/modbus"
	"time"
	"toyota-client1/app/socket"
	"toyota-client1/init/global"
	j_log "toyota-client1/init/j-log"
	"toyota-client1/model"
)

const NAME = "current"
const BASE_ADDR = uint16(0)

var Client *modbus.ModbusClient

// Data 离心机原始点位数据
var Data *model.CurrentRaw

func Run() {
	defer func() {
		time.Sleep(3 * time.Second)
		Run()
	}()
	Data = &model.CurrentRaw{}
	addr := global.AppConfig.Section(NAME).Key("addr").String()
	protocol := global.AppConfig.Section(NAME).Key("protocol").String()
	portName := global.AppConfig.Section(NAME).Key("port_name").String()
	baudRate, _ := global.AppConfig.Section(NAME).Key("baud_rate").Int()
	dataBits, _ := global.AppConfig.Section(NAME).Key("data_bits").Int()
	stopBits, _ := global.AppConfig.Section(NAME).Key("stop_bits").Int()
	parityMode, _ := global.AppConfig.Section(NAME).Key("parity_mode").Int()
	scanRate, _ := global.AppConfig.Section(NAME).Key("scan_rate").Int()
	slaveID, _ := global.AppConfig.Section(NAME).Key("slave_id").Int()
	moduleID, _ := global.AppConfig.Section(NAME).Key("module_id").Int()

	flag.Parse()
	if addr == "" {
		j_log.LogError([]interface{}{fmt.Sprintf("【%s】 addr cant bt empty", NAME)})
		return
	}
	if protocol == "" {
		j_log.LogError([]interface{}{fmt.Sprintf("【%s】 protocol cant bt empty", NAME)})
		return
	}
	if scanRate <= 0 {
		scanRate = 1000
	}
	if protocol != "rtu" && protocol != "tcp" {
		j_log.LogError([]interface{}{fmt.Sprintf("【%s】 protocol must be one of RTU, TCP", NAME)})
		return
	}
	var err error
	url := ""
	if protocol == "rtu" {
		url = protocol + "://" + portName
		j_log.LogInfo([]interface{}{fmt.Sprintf("【%s】 is connecting to %s", NAME, url)})
		switch uint(parityMode) {
		case modbus.PARITY_NONE:
		case modbus.PARITY_EVEN:
		case modbus.PARITY_ODD:
		default:
			j_log.LogError([]interface{}{fmt.Sprintf("【%s】 modbus rtu奇偶校验只能是 [0,1,2]", NAME)})
			return
		}
		Client, err = modbus.NewClient(&modbus.ClientConfiguration{
			URL:      url,
			Speed:    uint(baudRate),   // default
			DataBits: uint(dataBits),   // default, optional
			Parity:   uint(parityMode), // default, optional
			StopBits: uint(stopBits),   // default if no parity, optional
			Timeout:  300 * time.Millisecond,
		})
	} else {
		url = protocol + "://" + addr
		j_log.LogInfo([]interface{}{fmt.Sprintf("【%s is connecting to %s", NAME, url)})
		Client, err = modbus.NewClient(&modbus.ClientConfiguration{
			URL:     url,
			Timeout: 1 * time.Second,
		})
	}
	if err != nil {
		j_log.LogError([]interface{}{fmt.Sprintf("【%s】 modbus.NewClient error ", NAME)})
		return
	}
	err = Client.Open()
	if err != nil {
		j_log.LogError([]interface{}{fmt.Sprintf("【%s】 client.Open error ", NAME)})
		return
	}
	defer Client.Close()
	j_log.LogInfo([]interface{}{fmt.Sprintf("【%s】%s", NAME, "modbus连接成功")})
	// 开始循环循环读
	for {
		err0 := Client.SetUnitId(uint8(slaveID))
		if err0 != nil {
			j_log.LogWarning([]interface{}{fmt.Sprintf("【%s】SetUnitId error ", NAME)})
			return
		}
		buffer, err2 := Client.ReadRegisters(BASE_ADDR, 27, modbus.HOLDING_REGISTER)
		if err2 != nil {
			j_log.LogWarning([]interface{}{fmt.Sprintf("【%s】ReadRegisters part1 %v", NAME, err2.Error())})
			return
		} else {
			Data.SlaveID = uint8(slaveID)
			Data.D40001 = float64(buffer[0]) / 100.0
			Data.D40002 = float64(buffer[1]) / 100.0
			Data.D40003 = float64(buffer[2]) / 100.0
			Data.D40004 = float64(buffer[3]) / 100.0
			Data.D40005 = float64(buffer[4]) / 100.0
			Data.D40006 = float64(buffer[5]) / 100.0
			Data.D40007 = float64(buffer[6]) / 100.0
			Data.D40008 = float64(buffer[7]) / 100.0

			Data.D40009 = buffer[8]
			Data.D40010 = buffer[9]
			Data.D40011 = buffer[10]
			Data.D40020 = int16(buffer[19])
			Data.D40021 = int16(buffer[20])
			Data.D40022 = int16(buffer[21])
			Data.D40023 = int16(buffer[22])
			Data.D40024 = int16(buffer[23])
			Data.D40025 = int16(buffer[24])
			Data.D40026 = int16(buffer[25])
			Data.D40027 = int16(buffer[26])
		}
		jsonB, _ := json.Marshal(Data)
		_ = socket.Client.SendMessage(moduleID, NAME, string(jsonB))
		time.Sleep(time.Duration(scanRate) * time.Millisecond)
	}
}
